package com.ai.dmc.utils.json;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.PropertyFilter;
import net.sf.json.xml.XMLSerializer;

import org.apache.commons.beanutils.BeanUtils;

import com.ai.dmc.utils.export.excelhelper.CellBean;

/**
 * 
 * <p>Title: JsonUtil.java</p>
 * <p>Description: JSON串与对象、xml等相互转换的工具类</p>
 * <p>Copyright: Copyright (c) 2009</p>
 * <p>Company: 亚信科技（中国）有限公司</p>
 * @author chenhui2
 * @version 1.0 
 *
 */
@SuppressWarnings("unchecked")
public class JsonUtil {
	/**
	 * Object转换成JsonObject数据对象 ，Object可以是String形式的Json字符串
	 * 也可以是Map,List,Array之类的数据结构
	 * @param o
	 * @return
	 * JSONObject
	 *
	 */
	public static JSONObject Object2Json(Object o) {
		return JSONObject.fromObject(o);
	}

	/**
	 * 集合转换成JSONArray数据对象
	 * @param o
	 * @return  JSONArray
	 *
	 */
	public static JSONArray Object2Json(List o) {
		return JSONArray.fromObject(o);
	}

	/**
	 * 
	 * Object转换成JsonObject数据对象， List中是不需要转的属性列表 <br/>
	 * @param o			String形式的Json字符串或Map,List,Array之类的数据结构
	 * @param filter	过滤的属性集合
	 * @return  JSONObject
	 *
	 */
	public static JSONObject Object2Json(Object o, List filter) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setJsonPropertyFilter(new IgnorePropertyFilter(filter));
		return JSONObject.fromObject(o, jsonConfig);
	}

	/**
	 * 
	 * 集合转换成JSONArray数据对象， filter中是要过滤的属性列表 <br/>
	 * @param list		对象集合
	 * @param filter	过滤的属性集合
	 * @return
	 * JSONArray
	 *
	 */
	public static JSONArray Object2Json(List list, List filter) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setJsonPropertyFilter(new IgnorePropertyFilter(filter));
		return JSONArray.fromObject(list, jsonConfig);
	}

	/**
	 * 
	 * Object转换成JsonObject数据对象
	 * @param obj	String形式的Json字符串 也可以是Map,List,Array之类的数据结构
	 * @param propertyFilter	实现net.sf.json.util.PropertyFilter接口的过滤器
	 * @return
	 * JSONObject
	 *
	 */
	public static JSONObject Object2Json(Object obj, PropertyFilter propertyFilter) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setJsonPropertyFilter(propertyFilter);
		return JSONObject.fromObject(obj, jsonConfig);
	}

	/**
	 * 集合转换成JSONArray数据对象
	 * @param list
	 * @param propertyFilter	实现net.sf.json.util.PropertyFilter接口的过滤器
	 * @return
	 * JSONArray
	 *
	 */
	public static JSONArray Object2Json(List list, PropertyFilter propertyFilter) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setJsonPropertyFilter(propertyFilter);
		return JSONArray.fromObject(list, jsonConfig);
	}

	/**
	 * 
	 * Object转换成Json格式的字符串 
	 * 
	 * @param o		String形式的Json字符串 也可以是Map，List之类的数据结构
	 * @return
	 * String
	 *
	 */
	public static String Object2JsonString(Object o) {
		return Object2Json(o).toString();
	}

	/**
	 * 
	 * 集合转换成Json格式的字符串 
	 * 
	 * @param o
	 * @return
	 * String
	 *
	 */
	public static String Object2JsonString(List o) {
		return Object2Json(o).toString();
	}

	/**
	 * 
	 * Object转换成Json格式的字符串
	 * @param o			String形式的Json字符串也可以是Map，List之类的数据结构
	 * @param filter		不需要转的属性列表
	 * @return
	 * String
	 *
	 */
	public static String Object2JsonString(Object o, List filter) {
		return Object2Json(o, filter).toString();
	}

	/**
	 * 
	 * 集合转换成Json格式的字符串
	 * @param list
	 * @param filter	不需要转的属性列表
	 * @return
	 * String
	 *
	 */
	
	public static String Object2JsonString(List list, List filter) {
		return Object2Json(list, filter).toString();
	}

	   /**
     * Object转换成JSONArray数据对象 ，Object可以是String形式的Json字符串
     * 也可以是Map,List,Array之类的数据结构
     * @param o
     * @return
     * JSONObject
     *
     */
	
    public static JSONArray Object2JsonArray(Object o) {
        return JSONArray.fromObject(o);
    }
    
	/**
	 * 
	 * 将Json各式的字符串转换bean 如果Json字符串中的属性在bean中不存在，则此属性会忽略
	 * 如果Json字符串中不存在bean中定义的属性，则不会覆盖bean中原有属性的取值
	 * @param js
	 * @param c
	 * @return
	 * Object
	 *
	 */
	public static Object JsonString2Bean(String js, Class c) {
		JSONObject jo = JSONObject.fromObject(js);
		List<CellBean> cellList = new ArrayList<CellBean>();
		if(jo.containsKey("headers") && jo.getJSONArray("headers").size() > 0){
			JSONArray jarr = jo.getJSONArray("headers");
			for(int i = 0; i < jarr.size(); i++){
				JSONObject jobj = (JSONObject)jarr.get(i);
				Map map1 = (Map) JSONObject.toBean(jobj, Map.class);
				CellBean cellbean = new CellBean();
				try {
					BeanUtils.copyProperties(cellbean, map1);
					cellList.add(cellbean);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		Map<String, List<CellBean>> map = (Map<String, List<CellBean>>) JSONObject.toBean(jo, Map.class);
		if(cellList.size() > 0){
			map.put("headers", cellList);
		}
		Object bean = null;
		try {
			bean = c.newInstance();
			BeanUtils.copyProperties(bean, map);
			
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return bean;
	}

	/**
	 * 
	 * 将json字符串转换为对应的map对象
	 * @param jsonString
	 * @param map 如果map中包含有集合，并且集合中包含有其他的对象，这时候，需要定义一个Map对象，Key值为集合的名字，Value值为集合对象的Class
	 * @return
	 */
	public static <T> Map<String,T> JsonString2Map(String jsonString,@SuppressWarnings("rawtypes") Map<String, Class> map){
        JSONObject obj=JSONObject.fromObject(jsonString);
        Map<String,T> maps = (Map<String,T>) JSONObject.toBean(obj,Map.class,map);
        return maps;
	}
    
	/**
	 * 
	 * 将Json格式的字符串转换成xml格式 jsonString = "{'name':'json','bool':true,'int':1}";
	 * xmlString: <o class="object"> <name type="string">json</name> <bool
	 * type="boolean">true</bool> <int type="number">1</int> </o>
	 * 
	 * @param s
	 * @return
	 * String
	 *
	 */
	public static String JsonString2Xml(String s) {
		XMLSerializer xml = new XMLSerializer();
		String xmlString = xml.write(Object2Json(s));
		return xmlString;
	}

	/**
	 * 将xml格式的字符串转换成Json格式的字符串 最好是根据不同类型的Json字符串转换后的xml格式要求进行xml的组装
	 * @param s
	 * @return
	 * String
	 *
	 */
	public static String Xml2JsonString(String s) {
		XMLSerializer xml = new XMLSerializer();
		JSON js = xml.read(s);
		return js.toString();
	}
	
	/**
     * 将json对象转换成Map
     * 
     * @param jsonObject
     *            json对象
     * @return Map对象
     */
    public static Map<String, String> jsonObjectToMap(JSONObject jsonObject)
    {
        Map<String, String> resultMap = new HashMap<String, String>();
        Iterator<String> iterator = jsonObject.keys();
        String key = null;
        String value = null;
        while (iterator.hasNext())
        {
            key = iterator.next();
            value = jsonObject.getString(key);
            resultMap.put(key, value);
        }
        return resultMap;
    }

    /**
     * JSONArray数组转化成List<Map<String,String>>
     * 
     * @param jsonArray
     *            json数组
     * @return List<Map<String,String>>
     */
    public static  List<Map<String, String>> jsonArrayToListMap(JSONArray jsonArray) {
        Map<String, String> jsonMap = null;
        List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = JSONObject.fromObject(jsonArray.get(i));
            jsonMap = jsonObjectToMap(jsonObject);
            resultList.add(jsonMap);
        }
        return resultList;
    }

    /**
     * 将Java的Map转换成JSON字符串， 只转换第一层数据
     * 
     * @param map
     * @return
     */
    public static String simpleMapToJsonStr(Map<?, ?> map) {
        if (map == null || map.isEmpty()) {
            return "null";
        }
        String jsonStr = "{";
        Set<?> keySet = map.keySet();
        for (Object key : keySet) {
            jsonStr += "\"" + key + "\":\"" + map.get(key) + "\",";
        }
        jsonStr = jsonStr.substring(0, jsonStr.length() - 1);
        jsonStr += "}";
        return jsonStr;
    }
}
